﻿using System.Text;
using KinonekoSoftware.ArkSpark.Core.Messages;
using KinonekoSoftware.ArkSpark.Documents.Primitives;
using KinonekoSoftware.Extensions.Collections;

namespace KinonekoSoftware.ArkSpark.Runtimes
{
    partial class ArkSparkMQ
    {

        #region EventHandlers

        protected void NewSelectionEventHandler(IArkSparkEvent @event)
        {
            if (@event is not NewSelectionEventArgs args)
            {
                return;
            }

            var oldOne = Selection;
            var newOne = (DocumentElementPresenter)args.EditingItem;

            //
            //
            OnSelectionChangedInternal(oldOne, newOne);
        }
        
        
        private void NewVisibleScopedEventArgsHandler(IArkSparkEvent @event)
        {
            if (@event is not NewVisibleScopedEventArgs args)
            {
                return;
            }

            //
            //
            _VisibleElements.AddMany(args.ElementsInScope, true);

            //
            //
            OnNewVisibleScoped(args.ElementsInScope);
        }

        protected virtual void OnNewVisibleScoped(IEnumerable<DocumentElementPresenter> presenters)
        {
            
        }

        #endregion

        #region TextModelPostProcess

        private static List<string> SplitTextModelContent(string sourceString)
        {
            var sb         = new StringBuilder();
            var stringList = new List<string>();

            foreach (var ch in sourceString.Where(x => x != '\r'))
            {
                if (ch == '\n')
                {
                    var newString = sb.ToString().Trim();
                    if (!string.IsNullOrEmpty(newString)) stringList.Add(newString);
                    sb.Clear();
                }

                //
                //
                sb.Append(ch);
            }

            if (sb.Length > 0)
            {
                var newString = sb.ToString().Trim();
                if (!string.IsNullOrEmpty(newString)) stringList.Add(newString);
            }

            return stringList;
        }

        private void TextModelPostProcess(IArkSparkTextModel iArkSparkTextModel)
        {
            //
            // 切分所有内容
            var sentences = SplitTextModelContent(iArkSparkTextModel.Content);

            //
            // 确定文本需要拆分
            if (sentences.Count <= 1)
            {
                return;
            }

            //
            //
            iArkSparkTextModel.Content    = sentences[0];
            iArkSparkTextModel.IsModified = false;

            var index    = Collection.IndexOf((DocumentElementPresenter)iArkSparkTextModel);
            var iterator = sentences.Skip(1).Select(CreateParagraph).Select(CreateParagraph);

            if (index < 0)
            {
                foreach (var paragraph in iterator)
                {
                    Collection.Add(paragraph);
                }
            }
            else
            {
                foreach (var paragraph in iterator)
                {
                    Collection.Insert(index++, paragraph);
                }
            }
        }

        #endregion

        #region SelectionChanged

        private async void OnSelectionChangedInternal(DocumentElementPresenter oldOne, DocumentElementPresenter newOne)
        {
            if (oldOne is IArkSparkTextModel iArkSparkTextModel && iArkSparkTextModel.IsModified)
            {
                //
                // 如果当前元素是一个文本元素，并且文本元素被修改过
                // 就需要扫描是否为多行，并且拆分文段。
                TextModelPostProcess(iArkSparkTextModel);
            }

            //
            // 触发选项变更
            OnSelectionChanged(oldOne, newOne);

            //
            //
            Selection = newOne;
            RaiseUpdated(nameof(Selection));

            //
            //
            Selected?.Invoke(Selection.UseWYSIWYGEditor, Selection);

            //
            //
            if (((IArkSparkModel)newOne).UseExternalEditor)
            {
                //
                //
                var task = ExternalProcessing?.Invoke(newOne);


                if (task is null)
                {
                    return;
                }

                //
                //
                await task;
            }
        }

        protected virtual void OnSelectionChanged(DocumentElementPresenter oldOne, DocumentElementPresenter newOne)
        {

        }

        #endregion

        protected void Select(DocumentElementPresenter presenter)
        {
            if (presenter is null)
            {
                return;
            }

            ForwardHandler?.Invoke(new NewSelectionEventArgs
            {
                EditingItem     = presenter,
                WYSIWYGEditMode = presenter.UseWYSIWYGEditor,
            });
        }

        /// <summary>
        /// 当前选择的元素。
        /// </summary>
        public DocumentElementPresenter Selection { get; private set; }

        public event Action<bool, DocumentElementPresenter> Selected;
        
        /// <summary>
        /// 当文本需要外部编辑器来修改属性时，调用该事件。
        /// </summary>
        public event Func<DocumentElementPresenter, Task>   ExternalProcessing;
    }
}